﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Text;
using PM.Entities;

namespace PM.BusinessLayer
{
    public class SheduleController
    {
        /**
         * Вибирає з БД дні для розкладу
         **/
        public List<Day> SelectDays()
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Day>().ToList();
            }
        }

        public List<Group> SelectGroups()
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Group>().ToList();
            }
        }

        public List<User> SelectUsers(int dayID, int lessonID)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                var list = dc.GetTable<Shedule>().Where(r => r.LessonNumberID == lessonID && r.DayID == dayID).Select(r => r.User);
                return dc.GetTable<User>().Except(list).ToList();
            }
        }

        public List<Subject> SelectSubject()
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Subject>().ToList();
            }
        }

        public List<Speciality> SelectSpecialities()
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Speciality>().ToList();
            }
        }

        public List<LessonNumber> SelectLessonNumber(int groupID, int dayID, int course)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                var numLesson = dc.GetTable<Shedule>().Where(r => r.DayID == dayID && r.GroupID == groupID && r.Course == course).Select(r => r.LessonNumber);
                return dc.GetTable<LessonNumber>().Except(numLesson).ToList();
            }
        }

        public int GetCount()
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Shedule>().Count();
            }
        }

        public List<Shedule> SelectShedules(int startIndex, int maxRowCount)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                //DataLoadOptions дозволяє разом із сутністю підтягнути
                //задані сутності з якими перша має зовнішній зв'язок
                DataLoadOptions options = new DataLoadOptions();
                options.LoadWith<Shedule>(r => r.Subject);
                options.LoadWith<Shedule>(r => r.Group);
                options.LoadWith<Shedule>(r => r.User);
                options.LoadWith<Shedule>(r => r.Day);
                options.LoadWith<Shedule>(r => r.Speciality);
                options.LoadWith<Shedule>(r => r.LessonNumber);
                dc.LoadOptions = options;
                return dc.GetTable<Shedule>().Skip(startIndex).Take(maxRowCount).ToList();
            }
        }

        public void InsertSheduleItem(Shedule shedule)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                dc.GetTable<Shedule>().InsertOnSubmit(shedule);
                dc.SubmitChanges();
            }
        }

        public void DeleteSheduleItem(Shedule value)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                dc.GetTable<Shedule>().DeleteOnSubmit(dc.GetTable<Shedule>().SingleOrDefault(s => s.SheduleID == value.SheduleID));
                dc.SubmitChanges();
            }
        }

        private List<Group> GetGroups(/*int specialityID*/)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Group>().ToList();
            }
        }

        private Group GetGroup(int groupID)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Group>().SingleOrDefault(g => g.GroupID == groupID);
            }
        }

        /****************************************************************
         * Приватний метод, який повертає скорочену назву спеціальності
         * **************************************************************/
        private string ShortName(string specialityName, int groupID)
        {
            string[] words = specialityName.Split(' ');
            StringBuilder name = new StringBuilder();
            for (int i = 0; i < words.Length; i++)
            {
                name.Append(words[i][0]);
            }
            name.Append(String.Format("-{0}", groupID.ToString()));
            return name.ToString().ToUpper();
        }

        #region Select Shedule Data Item

        /************************************************
         * формує розклад по заданим вхідним параметрам
         * **********************************************/
        public List<Shedule> SelectForDay(int course, int specialityID, string day, int groupID)
        {
            int dayID = GetDayIDByName(day);
            using (DataContext dc = Infrastructure.DataContext)
            {
                DataLoadOptions options = new DataLoadOptions();
                options.LoadWith<Shedule>(r => r.Subject);
                options.LoadWith<Shedule>(r => r.User);
                options.LoadWith<Shedule>(r => r.LessonNumber);
                dc.LoadOptions = options;

                /**************************************************
                 * Вибираємо з БД записи де курс, спеціальність, 
                 * день і група = заданим вхідним параметрам
                 * і сортуємо( OrderBy() ) по номеру пари
                 * ************************************************/
                return
                    dc.GetTable<Shedule>().Where(
                        s => s.Course == course && s.SpecialityID == specialityID && s.DayID == dayID && s.GroupID == groupID).OrderBy(
                        s => s.LessonNumber.LessonNumber1).ToList();
            }
        }

        /**************************************************************
         * Метод повертає ідентифікатор запису дня за його іменем
         * ************************************************************/
        private int GetDayIDByName(string day)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Day>().SingleOrDefault(d => d.Name == day).DayID;
            }
        }

        #endregion

        public static string GetSpecialityNameById(int i)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Speciality>().SingleOrDefault(s => s.SpecialityID == i).Name;
            }
        }

        public static string GetSpecialityShortNameById(int i)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Speciality>().SingleOrDefault(s => s.SpecialityID == i).ShortName;
            }
        }

        public static string GetGroupNumberById(int id)
        {
            using (DataContext dc = Infrastructure.DataContext)
            {
                return dc.GetTable<Group>().SingleOrDefault(g => g.GroupID == id).GroupNumber.ToString();
            }
        }
    }
}